package com.uex.dev.manage.common.utils;

import java.util.concurrent.*;

/**
 * @author wangc
 * @create 2023/10/30
 * @description
 */
public class ThreadPoolUtil {
    public static volatile ExecutorService IO_EXECUTOR = null;

    public static volatile ExecutorService CPU_EXECUTOR = null;

    static Integer KERNEL_NUM = Runtime.getRuntime().availableProcessors();

    /**
     * 提交IO密集型任务
     * @param task
     * @return
     */
    public static Future submitIoTask(Callable task) {
        initIfNecessary();
        return IO_EXECUTOR.submit(task);
    }

    public static void submitIoTask(Runnable task) {
        initIfNecessary();
        IO_EXECUTOR.submit(task);
    }

    /**
     * 提交cpu密集型任务
     * @param task
     * @return
     */
    public static Future submitCpuTask(Callable task) {
        initIfNecessary();
        return CPU_EXECUTOR.submit(task);
    }


    private static void initIfNecessary() {
        if (IO_EXECUTOR == null) {
            synchronized(ThreadPoolUtil.class) {
                if (IO_EXECUTOR == null) {
                    //IO密集型线程池,避免CPU在等待IO的时候过于浪费,线程数等于2*CPU个数 + 1
                    //+1是为了避免某个线程挂掉以后,导致某个CPU空闲
                    int ioThreadNum = KERNEL_NUM * 2 + 1;
                    IO_EXECUTOR = new ThreadPoolExecutor(ioThreadNum, ioThreadNum, 0, TimeUnit.SECONDS, new LinkedBlockingQueue<>());

                    //CPU密集型线程池, 避免过多的线程切换, 线程数就等于CPU个数+1就好了
                    int cpuThreadNum = KERNEL_NUM + 1;
                    CPU_EXECUTOR = new ThreadPoolExecutor(cpuThreadNum, cpuThreadNum, 0, TimeUnit.SECONDS, new LinkedBlockingQueue<>());
                }
            }
        }
    }
}
